    //
//  MemberCheckinViewController.m
//  BVAttend
//
//  Created by Allen Thomas on 10/20/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "MemberCheckinViewController.h"
#import "BVCMSAppDelegate.h"
#import "AttendCell.h"
#import "AttendSearchFormViewController.h"
#import "GenericXMLParser.h"
#import "MeetingMemberRecord.h"
#import "AttendanceConnection.h"

@implementation MemberCheckinViewController

@synthesize theTableView, meetingId;
@synthesize organizationId, organizationName, meetingDate;
@synthesize attendanceConnectionsInProgress;
@synthesize meetingRoll;

#define SPINNER_SIZE 25

- (void)viewDidLoad {
	self.title = @"Check-in";

	UIBarButtonItem* addButton = [[UIBarButtonItem alloc] initWithTitle:@"Add Visitor" style:UIBarButtonItemStylePlain target:self action:@selector(addVisitor:)];
	self.navigationItem.rightBarButtonItem = addButton;
	[addButton release];
	
	NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"LoadingView" owner:self options:nil];
    loadingView = [nibObjects objectAtIndex:0];
	loadingView.center = CGPointMake(160, 160);
	[self.view addSubview:loadingView];
	
	checked = [UIImage imageNamed:@"check.png"];
	unchecked = [UIImage imageNamed:@"uncheck.png"]; 
	
	[self getMeetingMembers];
}



#pragma mark Members Retrieval Actions

- (void)getMeetingMembers {
	
	//start network activity
	[self.view bringSubviewToFront:loadingView];
	loading = YES;
	
	NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
	[formatter setDateFormat:@"MM/dd/yy hh:mma"];
	
	BVCMSAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
	
	NSString *urlString = [NSString stringWithFormat:@"https://%@/iphone/RollList/%@?datetime=%@", 
						   delegate.cmsServer, 
						   organizationId, 
						   [formatter stringFromDate:meetingDate] ];
	
	urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	NSLog(@"%@", urlString);
	NSURL *url = [NSURL URLWithString:urlString];
	
	HttpConnectionHandler *connectionHandler = [HttpConnectionHandler withURL:url andUsername:delegate.username andPassword:delegate.password];
	
	connectionHandler.errorCallback = @selector(getMeetingMembers_error_callback:);
	connectionHandler.callback = @selector(getMeetingMembers_callback:);
	connectionHandler.delegate = self;
	[connectionHandler processRequest];
	
	[formatter release];
}

- (void)recordVisit: (NSString *)peopleId {
	//NSLog(@"adding %@", (NSString *)[pNotification object]);
	//start network activity
	[self.view bringSubviewToFront:loadingView];
	loading = YES;
	
	BVCMSAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
	
	NSString *urlString = [NSString stringWithFormat:@"https://%@/iphone/RecordVisit/%@?PeopleId=%@", 
						   delegate.cmsServer, 
						   self.meetingId, 
						   peopleId ];
	
	urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	NSLog(@"%@", urlString);
	NSURL *url = [NSURL URLWithString:urlString];
	
	HttpConnectionHandler *connectionHandler = [HttpConnectionHandler withURL:url andUsername:delegate.username andPassword:delegate.password];
	
	connectionHandler.errorCallback = @selector(getMeetingMembers_error_callback:);
	connectionHandler.callback = @selector(getMeetingMembers_callback:);
	connectionHandler.delegate = self;
	[connectionHandler processRequest];
	
}

- (void)addNewPerson:(NSString *)paramString {
	//start network activity
	[self.view bringSubviewToFront:loadingView];
	loading = YES;
	
	BVCMSAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
	
	NSString *urlString = [NSString stringWithFormat:@"https://%@/iPhone/AddPerson/%@?%@", 
						   delegate.cmsServer, 
						   self.meetingId, 
						   paramString ];
	
	urlString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
	NSLog(@"%@", urlString);
	NSURL *url = [NSURL URLWithString:urlString];
	
	HttpConnectionHandler *connectionHandler = [HttpConnectionHandler withURL:url andUsername:delegate.username andPassword:delegate.password];
	
	connectionHandler.errorCallback = @selector(getMeetingMembers_error_callback:);
	connectionHandler.callback = @selector(getMeetingMembers_callback:);
	connectionHandler.delegate = self;
	[connectionHandler processRequest];
	
}



- (void)getMeetingMembers_callback:(NSData *)data {
	NSString *output = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
	NSLog(@"%@", output);
	[output release];
	
	[self parseXml:data];
	
	if ([meetingRoll count] > 0 ) {
		[self setupIndexData];
		[self.theTableView reloadData];
		
		// stop network activity
		[self.view sendSubviewToBack:loadingView];
		loading = NO;
	} else {
		UIAlertView *connectionError = [[UIAlertView alloc] initWithTitle:@"Roll List Error" message:@"There was a problem retrieving the roll list." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[connectionError show];
		[connectionError release];
	}
	
}

- (void)getMeetingMembers_error_callback:(NSError *)error {
	NSLog(@"Connection failed! Error - %@",
          [error localizedDescription]);
	
	// stop network activity
	[self.view sendSubviewToBack:loadingView];
	loading = NO;
	
	UIAlertView *connectionError = [[UIAlertView alloc] initWithTitle:@"Connection Error" message:[error localizedDescription] delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[connectionError show];
	[connectionError release];
}


#pragma mark XML Parsing

/*
 Callback functions that handles the 'organizations' tag
 */
-(void) handleElement_RollList: (NSDictionary*) attributes {
	NSLog(@"RollList handler");
	if(self.meetingRoll) {
		[self.meetingRoll removeAllObjects];
	} else {
		self.meetingRoll = [[NSMutableArray alloc] init];
	}
	[self setMeetingId:[attributes valueForKey:@"MeetingId"]];
	NSLog(@"MeetingId set to %@", self.meetingId);
}

/*
 Callback function that handles the 'organization' tag.
 */
-(void) handleElement_Person: (NSDictionary*) attributes {
	NSLog(@"Person handler");
	MeetingMemberRecord* member = [[MeetingMemberRecord alloc] init];
	member.name = [attributes valueForKey:@"Name"];
	member.meetingId = meetingId;
	member.peopleId = [attributes valueForKey:@"Id"];
	member.attended = [attributes valueForKey:@"Attended"];
	member.member = [attributes valueForKey:@"Member"];
	
	[self.meetingRoll addObject:member];
	[member release];
}


/*
 Creates an xml parser and begins parsing the xml data.
 */
-(void) parseXml:(NSData *)data {
	NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
	
	//Initialize the delegate.
	GenericXMLParser *parser = [[GenericXMLParser alloc] init];
	parser.delegate = self;
	
	//Set delegate
	[xmlParser setDelegate:parser];
	
	//Start parsing the XML file.
	BOOL success = [xmlParser parse];
	
	if(success)
		NSLog(@"No Errors");
	else
		NSLog(@"Error Error Error!!!");
	
	[parser release];
	[xmlParser release];
}





#pragma mark Table View Methods

- (void)setupIndexData {
	members = 0;
	visitors = 0;
	
	for (MeetingMemberRecord *objData in self.meetingRoll) {		
		if( [objData.member isEqualToString:@"True"] ) {
			members++;
		} else {
			visitors++;
		}
	}
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 2;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	if(section == 0 ) 
		return members;
	else 
		return visitors;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    if(section == 0 ) 
		return @"Members";
	else 
		return @"Visitors";
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
	if( [[attendanceConnectionsInProgress allKeys] count] == 0 ) {
		if (editingStyle == UITableViewCellEditingStyleDelete) {
			[self startJoinUnenroll:[self getPerson:indexPath] forIndexPath:indexPath];
		}
	} else {
		UIAlertView *commitError = [[UIAlertView alloc] initWithTitle:@"Cannot Proceed" message:@"Please wait until all attendance changes have finished" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[commitError show];
		[commitError release];
	}
}

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
	if(indexPath.section == 0) {
		return @"unenroll";
	} else {
		return @"join";
	}
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
	static NSString *CustomCellIdentifier = @"AttendCellIdentifier ";
	AttendCell *cell = (AttendCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
	if (cell == nil) {         
		cell = [[[NSBundle mainBundle] loadNibNamed:@"AttendCell" owner:self options:nil] objectAtIndex:0];
	}
	
	MeetingMemberRecord *objPerson = [self getPerson:indexPath];	
	
	cell.nameLabel.text	= objPerson.name;
	if( [objPerson.member isEqual:@"False"] ) {
		cell.nameLabel.textColor = [UIColor blueColor];
	}

	AttendanceConnection *attendanceConnection = [attendanceConnectionsInProgress objectForKey:indexPath];
    if (attendanceConnection == nil || rollConnection.indexPathInTableView == indexPath) {
		if ([objPerson.attended isEqualToString:@"True"]) {
			[cell.checkImage setImage:checked];
		} else {
			[cell.checkImage setImage:unchecked];
		}
		
		//[cell.checkImage setImage:objPerson.attendIcon];
		//[cell.spinner stopAnimating];
	} else {
		[self addSpinner:cell];
		//[cell.spinner startAnimating];
		//[cell.checkImage setImage:nil];
	}
	
	return cell;
	
}

- (void) addSpinner:(AttendCell*)cell {
	UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
	
	// Get center of cell (vertically) 
	int center = [cell frame].size.height / 2;
	
	// Size (width) of the text in the cell
	CGSize size = [[[cell nameLabel] text] sizeWithFont:[[cell nameLabel] font]];
	
	// Locate spinner in the center of the cell at end of text
	[spinner setFrame:CGRectMake(size.width + SPINNER_SIZE + 35, center - SPINNER_SIZE / 2, SPINNER_SIZE, SPINNER_SIZE)];
	[[cell contentView] addSubview:spinner];    
	
	[spinner startAnimating];
	[spinner release];
	
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	[tableView  deselectRowAtIndexPath:indexPath  animated:YES]; 

	if (!loading) {
		MeetingMemberRecord *record = [self getPerson:indexPath];
		[self startChangeAttendance:record forIndexPath:indexPath];
	} // if loading
	NSLog(@"updated cell");
}

- (void)startChangeAttendance:(MeetingMemberRecord *)meetingMemberRecord forIndexPath:(NSIndexPath *)indexPath {
	
    if (![[attendanceConnectionsInProgress allKeys] containsObject:indexPath]) {
		
		AttendCell *cell = (AttendCell*)[self.theTableView cellForRowAtIndexPath:indexPath];
		[self addSpinner:cell];
		//[cell.spinner startAnimating];
		//[cell.checkImage setImage:nil];
		
        AttendanceConnection *attendanceConnection = [[AttendanceConnection alloc] init];
        attendanceConnection.meetingMemberRecord = meetingMemberRecord;
        attendanceConnection.indexPathInTableView = indexPath;
        attendanceConnection.delegate = self;
		[attendanceConnection startDownload];
		[attendanceConnectionsInProgress setObject:attendanceConnection forKey:indexPath];
		[attendanceConnection release];   
	
		NSLog(@"Update Attendance");
		
    }
	
}

- (void)attendanceChangeFailed:(NSIndexPath *)indexPath {
	MeetingMemberRecord *record = [self getPerson:indexPath];
	[attendanceConnectionsInProgress removeObjectForKey:indexPath];
	
	[theTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
	
	UIAlertView *commitError = [[UIAlertView alloc] initWithTitle:@"Attendance Change Failed" message:@"There was an error attempting to change attendance." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[commitError show];
	[commitError release];
	
	NSLog(@"Attendance Failed: %@", record.name);
}


- (void)attendanceDidChange:(NSIndexPath *)indexPath {
	MeetingMemberRecord *record = [self getPerson:indexPath];
	[attendanceConnectionsInProgress removeObjectForKey:indexPath];
	
	[theTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
	
	NSLog(@"Attendance Changed: %@", record.attended);
}

- (void)startJoinUnenroll:(MeetingMemberRecord *)meetingMemberRecord forIndexPath:(NSIndexPath *)indexPath {
	if(rollConnection == nil) {
		AttendCell *cell = (AttendCell*)[self.theTableView cellForRowAtIndexPath:indexPath];
		
		[self addSpinner:cell];
		
		rollConnection = [[JoinUnenrollConnection alloc] init];
        rollConnection.meetingMemberRecord = meetingMemberRecord;
		rollConnection.orgId = organizationId;
        rollConnection.indexPathInTableView = indexPath;
        rollConnection.delegate = self;
		[rollConnection startDownload];
		
		NSLog(@"Connecting");
	} else {
		NSLog(@"in progress");
		UIAlertView *commitError = [[UIAlertView alloc] initWithTitle:@"Cannot Proceed" message:@"Please wait until the previous unenroll or join has finished" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
		[commitError show];
		[commitError release];
	}
}

- (void)joinUnenrollCallback:(NSIndexPath *)indexPath {
	if(indexPath.section == 0) {
		MeetingMemberRecord *person = [self getPerson:indexPath];
		if( [person.attended isEqualToString:@"True"] ) {
			person.member = @"False";
			
			[rollConnection release];
			rollConnection = nil;
			
			[meetingRoll sortUsingSelector:@selector(compare:)];
			
			NSLog(@"joined organization");
		} else {
			int index = indexPath.row;
			if (indexPath.section == 1) {
				index += members;
			}
			
			[rollConnection release];
			rollConnection = nil;

			[meetingRoll removeObjectAtIndex:index];
			
			NSLog(@"unenrolled");
		}
	} else {
		// get the person
		MeetingMemberRecord *person = [self getPerson:indexPath];
		person.member = @"True";
		
		[rollConnection release];
		rollConnection = nil;
		
		[meetingRoll sortUsingSelector:@selector(compare:)];
		
		NSLog(@"joined organization");
	}
		   
	[self setupIndexData];
	[theTableView reloadData];
}

- (void)joinUnenrollFailed:(NSIndexPath *)indexPath {
	MeetingMemberRecord *record = [self getPerson:indexPath];
	[attendanceConnectionsInProgress removeObjectForKey:indexPath];
	
	[theTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
		
	UIAlertView *commitError = [[UIAlertView alloc] initWithTitle:@"Join/Unenroll Failed" message:@"There was an error attempting to Join or Unenroll." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
	[commitError show];
	[commitError release];

	[rollConnection release];
	rollConnection = nil;

	NSLog(@"Join/Unenroll Failed: %@", record.name);
}


- (MeetingMemberRecord*)getPerson:(NSIndexPath *)indexPath {
	int diff = 0;
    if(indexPath.section == 1) 
		diff = members;	
	return [meetingRoll objectAtIndex:(indexPath.row + diff) ];	
}

- (void)addVisitor:(id)sender {
	NSLog(@"Add Visitor");
	AttendSearchFormViewController *searchForm = [[AttendSearchFormViewController alloc]
												  initWithNibName:@"AttendSearchFormView" bundle:[NSBundle mainBundle]];
	
	[self.navigationController pushViewController:searchForm animated:YES];
	[searchForm release];
}


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {

	if( rollConnection ) {
		[rollConnection release];
	}
	[theTableView release];
	[meetingRoll release];
	[meetingId release];
	[organizationId release];
	[organizationName release];
	[meetingDate release];
	[attendanceConnectionsInProgress release];
    [super dealloc];
}


@end
